<template>
  <div :class="[
    'crud-pagination',
    `crud-pagination--${size}`,
    {
      'crud-pagination--background': background,
      'crud-pagination--small': small,
      'crud-pagination--disabled': disabled
    }
  ]">
    <el-pagination v-model:current-page="currentPageValue" v-model:page-size="pageSizeValue" v-bind="$attrs"
      :page-sizes="pageSizes" :size="size" :disabled="disabled" :background="background" :layout="layout" :total="total"
      :page-count="pageCount" :pager-count="pagerCount" :default-page-size="defaultPageSize"
      :default-current-page="defaultCurrentPage" :small="small" :prev-text="prevText" :next-text="nextText"
      :prev-icon="prevIcon" :next-icon="nextIcon" :jump-first-page="jumpFirstPage" :jump-last-page="jumpLastPage"
      :hide-on-single-page="hideOnSinglePage" class="crud-pagination__inner" @size-change="handleSizeChange"
      @current-change="handleCurrentChange" @prev-click="handlePrevClick" @next-click="handleNextClick" />
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { ElPagination } from 'element-plus'
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
import type { Component } from 'vue'

/**
 * 分页组件属性接口
 */
interface Props {
  /** 当前页数 */
  currentPage?: number
  /** 每页显示条目个数 */
  pageSize?: number
  /** 每页显示个数选择器的选项设置 */
  pageSizes?: number[]
  /** 组件大小 */
  size?: 'large' | 'default' | 'small'
  /** 是否禁用 */
  disabled?: boolean
  /** 是否为分页按钮添加背景色 */
  background?: boolean
  /** 组件布局，子组件名用逗号分隔 */
  layout?: string
  /** 总条目数 */
  total?: number
  /** 总页数，total 和 page-count 设置任意一个就可以达到显示页码的功能；如果要支持 page-sizes 的更改，则需要使用 total 属性 */
  pageCount?: number
  /** 设置最大页码按钮数。页码按钮的数量，当总页数超过该值时会折叠 */
  pagerCount?: number
  /** 默认的每页条数 */
  defaultPageSize?: number
  /** 默认的当前页数 */
  defaultCurrentPage?: number
  /** 是否使用小型分页样式 */
  small?: boolean
  /** 替代图标显示的上一页文字 */
  prevText?: string
  /** 替代图标显示的下一页文字 */
  nextText?: string
  /** 上一页的图标，比 prev-text 优先级更高 */
  prevIcon?: Component
  /** 下一页的图标，比 next-text 优先级更高 */
  nextIcon?: Component
  /** 是否可以跳转至第一页 */
  jumpFirstPage?: boolean
  /** 是否可以跳转至最后一页 */
  jumpLastPage?: boolean
  /** 只有一页时是否隐藏 */
  hideOnSinglePage?: boolean
}

/**
 * 组件事件接口
 */
interface Emits {
  /** 更新当前页数 */
  (e: 'update:currentPage', value: number): void
  /** 更新每页显示条目个数 */
  (e: 'update:pageSize', value: number): void
  /** pageSize 改变时会触发 */
  (e: 'size-change', value: number): void
  /** currentPage 改变时会触发 */
  (e: 'current-change', value: number): void
  /** 用户点击上一页按钮改变当前页后触发 */
  (e: 'prev-click', value: number): void
  /** 用户点击下一页按钮改变当前页后触发 */
  (e: 'next-click', value: number): void
}

// 定义组件属性，设置默认值
const props = withDefaults(defineProps<Props>(), {
  currentPage: 1,
  pageSize: 10,
  pageSizes: () => [5, 10, 20, 50, 100],
  size: 'default',
  disabled: false,
  background: true,
  layout: 'total, sizes, prev, pager, next, jumper',
  total: 0,
  pagerCount: 7,
  defaultPageSize: 10,
  defaultCurrentPage: 1,
  small: false,
  prevText: '',
  nextText: '',
  prevIcon: ArrowLeft,
  nextIcon: ArrowRight,
  jumpFirstPage: true,
  jumpLastPage: true,
  hideOnSinglePage: false
})

// 定义组件事件
const emit = defineEmits<Emits>()

// 计算属性：当前页数
const currentPageValue = computed({
  get: () => props.currentPage,
  set: (value: number) => {
    emit('update:currentPage', value)
  }
})

// 计算属性：每页显示条目个数
const pageSizeValue = computed({
  get: () => props.pageSize,
  set: (value: number) => {
    emit('update:pageSize', value)
  }
})

/**
 * 处理每页显示条目个数改变事件
 * @param value - 新的每页显示条目个数
 */
const handleSizeChange = (value: number): void => {
  emit('size-change', value)
}

/**
 * 处理当前页数改变事件
 * @param value - 新的当前页数
 */
const handleCurrentChange = (value: number): void => {
  emit('current-change', value)
}

/**
 * 处理上一页点击事件
 * @param value - 当前页数
 */
const handlePrevClick = (value: number): void => {
  emit('prev-click', value)
}

/**
 * 处理下一页点击事件
 * @param value - 当前页数
 */
const handleNextClick = (value: number): void => {
  emit('next-click', value)
}
</script>


<style lang="scss" scoped>
.crud-pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 16px 0;

  // ------------------------
  // Element Plus 样式穿透
  // ------------------------
  :deep(.el-pagination) {
    display: flex;
    align-items: center;
    gap: 8px;

    // ===== 通用按钮样式 =====
    .btn-prev,
    .btn-next {
      display: flex;
      align-items: center;
      justify-content: center;
      border: 1px solid $border-color-base;
      border-radius: 6px;
      background-color: $bg-color-white;
      color: $text-color-primary;
      transition: all 0.2s ease;
      cursor: pointer;

      &:hover:not(.is-disabled) {
        border-color: var(--primary-color, $primary-color);
        color: var(--primary-color, $primary-color);
        background-color: $hover-bg-light;
      }

      &.is-disabled {
        color: $text-color-disabled;
        border-color: $border-color-lighter;
        cursor: not-allowed;
        background-color: $bg-color-white;
      }
    }

    // ===== 页码样式 =====
    .el-pager {
      display: flex;
      align-items: center;
      gap: 4px;

      li {
        display: flex;
        align-items: center;
        justify-content: center;
        border: 1px solid $border-color-base;
        border-radius: 6px;
        background-color: $bg-color-white;
        color: $text-color-primary;
        transition: all 0.2s ease;
        cursor: pointer;

        &:hover:not(.is-active):not(.is-disabled) {
          border-color: var(--primary-color, $primary-color);
          color: var(--primary-color, $primary-color);
          background-color: $hover-bg-light;
        }

        &.is-active {
          background-color: var(--primary-color, $primary-color) !important;
          border-color: var(--primary-color, $primary-color) !important;
          color: #fff !important;
        }

        &.more {
          border: none;
          background-color: transparent;
          color: $text-color-muted;
        }
      }
    }

    // ===== 总数显示 =====
    .el-pagination__total {
      color: $text-color-secondary;
      font-size: 14px;
      margin-right: 16px;
    }

    // ===== 每页数量选择器 =====
    .el-pagination__sizes {
      .el-select .el-select__wrapper {
        border: 1px solid $border-color-base;
        border-radius: 6px;
        background-color: $bg-color-white;

        &:hover {
          border-color: var(--primary-color-light, $primary-color-light);
        }

        &.is-focused {
          border-color: var(--primary-color, $primary-color);
          box-shadow: 0 0 0 2px var(--primary-color-alpha-20, rgba(96, 122, 251, 0.2));
        }
      }
    }

    // ===== 跳页输入框 =====
    .el-pagination__jump {
      display: flex;
      align-items: center;
      gap: 8px;
      color: $text-color-secondary;
      font-size: 14px;

      .el-input__wrapper {
        width: 60px;
        border: 1px solid $border-color-base;
        border-radius: 6px;
        background-color: $bg-color-white;

        &:hover {
          border-color: var(--primary-color-light, $primary-color-light);
        }

        &.is-focus {
          border-color: var(--primary-color, $primary-color);
          box-shadow: 0 0 0 2px var(--primary-color-alpha-20, rgba(96, 122, 251, 0.2));
        }
      }
    }
  }

  // ------------------------
  // 尺寸样式
  // ------------------------
  &--large :deep(.el-pagination) {

    .btn-prev,
    .btn-next,
    .el-pager li {
      height: 40px;
      min-width: 40px;
      font-size: 16px;
    }

    .el-select__wrapper,
    .el-input__wrapper {
      height: 40px;
    }
  }

  &--default :deep(.el-pagination) {

    .btn-prev,
    .btn-next,
    .el-pager li {
      height: 32px;
      min-width: 32px;
      font-size: 14px;
    }

    .el-select__wrapper,
    .el-input__wrapper {
      height: 32px;
    }
  }

  &--small :deep(.el-pagination) {

    .btn-prev,
    .btn-next,
    .el-pager li {
      height: 24px;
      min-width: 24px;
      font-size: 12px;
    }

    .el-select__wrapper,
    .el-input__wrapper {
      height: 24px;
    }
  }

  // ------------------------
  // 状态样式
  // ------------------------
  &--disabled :deep(.el-pagination) {

    .btn-prev,
    .btn-next,
    .el-pager li {
      color: $text-color-disabled;
      cursor: not-allowed;

      &:hover {
        color: $text-color-disabled;
        background-color: transparent;
      }
    }
  }

  // ------------------------
  // 背景模式
  // ------------------------
  &--background :deep(.el-pagination) {

    .btn-prev,
    .btn-next,
    .el-pager li {
      background-color: $bg-color-gray;

      &:hover:not(.is-disabled):not(.is-active) {
        background-color: $hover-bg-light;
      }

      &.is-active {
        background-color: var(--primary-color, $primary-color);
        color: #fff;
      }
    }
  }
}

// ------------------------
// 深色模式适配
// ------------------------
@media (prefers-color-scheme: dark) {
  .crud-pagination {
    :deep(.el-pagination) {

      .btn-prev,
      .btn-next,
      .el-pager li {
        background-color: $bg-color-card-dark;
        border-color: $border-color-base-dark;
        color: $text-color-primary-dark;

        &:hover:not(.is-disabled) {
          background-color: $hover-bg-light-dark;
        }

        &.is-active {
          background-color: var(--primary-color, $primary-color);
          border-color: var(--primary-color, $primary-color);
          color: #fff;
        }

        &.is-disabled {
          color: $text-color-disabled-dark;
          border-color: $border-color-lighter-dark;
        }
      }

      .el-pagination__total {
        color: $text-color-secondary-dark;
      }

      .el-pagination__jump,
      .el-pagination__sizes {
        color: $text-color-secondary-dark;
      }
    }
  }
}
</style>
